
#ifndef __PAISLEYPARK__VECTORFUNCTIONFACTORY_H__
#define __PAISLEYPARK__VECTORFUNCTIONFACTORY_H__

#include "VectorFunction.h"
#include <map>
#include <cstring>

template <size_t DIM>
class VectorFunctionFactory {
public:
	typedef VectorFunction<DIM>* (*CreateVectorFunctionCallback)();
private:
	typedef std::map<std::string , CreateVectorFunctionCallback> CallbackMp;
public:
	bool RegisterFunction(const std::string _FunctionId, CreateVectorFunctionCallback _createFn);
	bool UnregisterFunction(const std::string _FunctionId);
	VectorFunction<DIM>* CreateFunction(const std::string _FunctionId);
	~VectorFunctionFactory(){};
	static VectorFunctionFactory<DIM>* Instance() {
		if(!__obj) {
			__obj = new VectorFunctionFactory<DIM>;
		}
		return __obj;
	};
private:
	static VectorFunctionFactory<DIM>* __obj;
	CallbackMp __callbacks;
	VectorFunctionFactory(){};
};


template <size_t DIM>
VectorFunctionFactory<DIM>* VectorFunctionFactory<DIM>::__obj = 0;

template <size_t DIM>
bool VectorFunctionFactory<DIM>::RegisterFunction(const std::string _FunctionId, CreateVectorFunctionCallback _createFn) {
	return __callbacks.insert(typename CallbackMp::value_type(_FunctionId, _createFn)).second;
};

template <size_t DIM>
bool VectorFunctionFactory<DIM>::UnregisterFunction(const std::string _FunctionId) {
	return __callbacks.erase(_FunctionId) == 1;
};

template <size_t DIM>
VectorFunction<DIM>* VectorFunctionFactory<DIM>::CreateFunction(const std::string _FunctionId) {
	typename CallbackMp::const_iterator i = __callbacks.find(_FunctionId);
	if(i == __callbacks.end()) {
		std::cerr << "Unknown Function Id." << std::endl;
		std::exit(-1);
	}
	return (i->second)();
}


#else
//Do nothing.
#endif
